//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "Unit1.h"
#include "Unit2.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
{

}
//---------------------------------------------------------------------------


void __fastcall TForm1::ClientSocket1Read(TObject *Sender,
      TCustomWinSocket *Socket)
{
    unsigned char *Clientbuf;
    int Clientlen;
    
    static int packetcount;

        Clientlen = Socket->ReceiveLength();

        if (Clientlen == 0){
                Memo1->Lines->Add("ClientbufLength is NULL.");
                return;
        } else {
        //Memo1->Lines->Add(Clientlen);
        }

        Clientbuf = new unsigned char[Clientlen];

        if (Clientbuf == NULL)
        {
                Memo1->Lines->Add("Clientbuf malloc failed");
                return;
        }

        Socket->ReceiveBuf(Clientbuf, Clientlen);
       /*
        if (CheckBox5->Checked && ServerSocket1->Active)
        if (Clientbuf[3] == 0xC4)
        {
                Memo1->Lines->Add("received c4");

                c4 = (unsigned char*) malloc(Clientlen);
                if (c4 == NULL)
                {
                 Memo1->Lines->Add("c4 malloc failed");
                 return;
                }
                memcpy(c4, Clientbuf, Clientlen);
                c4len = Clientlen;

        } else {
                ServerSocket1->Socket->Connections[0]->SendBuf(Clientbuf, Clientlen);
        }
         */
        if (CheckBox2->Checked)
        {
         AnsiString s;
         s.printf("data/raw/packet_%d.bin", packetcount);

         TFileStream * file = new TFileStream(s, fmCreate);
         file->Write(Clientbuf, Clientlen);

         
         delete(file);
        }



       packetcount++;
       StatusBar1->SimpleText = packetcount;

        process(Clientbuf, Clientlen);
       // free(segment);

       delete[](Clientbuf);
        //free(Clientbuf);
}
//---------------------------------------------------------------------------
void TForm1::KILL_EVENT()
{
        
            CheckBox5->Checked = 0;
            CheckBox6->Checked = 0;
            CheckBox7->Checked = 0;
            CheckBox8->Checked = 0;
            CheckBox9->Checked = 0;
            CheckBox10->Checked = 0;
            CheckBox11->Checked = 0;

            CheckBox12->Checked = 0;
            CheckBox13->Checked = 0;
            CheckBox14->Checked = 0;
            CheckBox15->Checked = 0;
            CheckBox16->Checked = 0;
            CheckBox17->Checked = 0;
            CheckBox18->Checked = 0;

            Label1->Caption = 0;
            Label2->Caption = 0;
            Label3->Caption = 0;
            Label4->Caption = 0;
            Label5->Caption = "Halt";

        return;
}
//---------------------------------------------------------------------------
void TForm1::process(unsigned char* buffer, int len)
{
          char bs = SOCKCMD_PACK;

        if(buffer[0] != SOCKCMD_PREQ && buffer[0] != SOCKCMD_EVTKILL)
            loghex("sock", buffer, len);

        switch(buffer[0])
        {
                case SOCKCMD_PREQ:
                case SOCKCMD_EVTKILL:
                              if(CheckBox3->Checked)
                              {
                                bs = SOCKCMD_PACK ;
                                ClientSocket1->Socket->SendBuf(&bs, 1);
                              }
                               StatusBar1->SimpleText = "Kill event";
                        break;

                default:
                break;

        }
        return;
}
void __fastcall TForm1::ClientSocket1Connecting(TObject *Sender,
      TCustomWinSocket *Socket)
{
        KILL_EVENT();
        
        StatusBar1->SimpleText = "Connecting...";
       // Memo1->Lines->Add( "Connecting" );
        Button1->Caption = "Disconnect";
}
//---------------------------------------------------------------------------

void __fastcall TForm1::Button1Click(TObject *Sender)
{


  if(Button1->Tag)
  {
    ClientSocket1->Active = false;
    Button1->Tag = 0;

  } else { ClientSocket1->Active = true;
     Button1->Tag = 1;
  }
 // if(!ClientSocket1->Socket->Connected)
 //       ClientSocket1->Active;
   /*
  if(ClientSocket1->Active)
    Button1->Caption = "Disconnect";
   else
    Button1->Caption = "Connect";
     */

}
//---------------------------------------------------------------------------

void __fastcall TForm1::ClientSocket1Connect(TObject *Sender,
      TCustomWinSocket *Socket)
{
        StatusBar1->SimpleText = "Connected";
}
//---------------------------------------------------------------------------

void __fastcall TForm1::ClientSocket1Disconnect(TObject *Sender,
      TCustomWinSocket *Socket)
{
   Button1->Caption = "Connect";
   StatusBar1->SimpleText = "Disconnected";
   KILL_EVENT();
}
//---------------------------------------------------------------------------

void __fastcall TForm1::Button2Click(TObject *Sender)
{
  char bs = SOCKCMD_REQIO;
  ClientSocket1->Socket->SendBuf(&bs, 1);
}
//---------------------------------------------------------------------------

void TForm1::loghex(char *what, unsigned char *buf, int length)
{
        AnsiString s;

	s.sprintf("%s: len: %d: ", what, length);

	if(buf != NULL)
	{
          for(int x = 0; x < length; x++) s.cat_printf("%02X ", buf[x]);
         }

	//s.printf("\n");
        Memo1->Lines->Add(s);
}
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------


void __fastcall TForm1::Button3Click(TObject *Sender)
{

        struct RS232_PACKET
        {
               char sock_cmd;

               char cmd;
               char ch0duty;
               char ch1duty;
               char OE;
               char sol12V;
               char sol24V;
               char checksum;
        }packet = {SOCKCMD_FWDRS232, 'F', 0xAA, 0xAA, 0xAA, 0xBB, 0xCC, 0x00};




      packet.checksum = packet.ch0duty + packet.ch1duty + packet.OE + packet.sol12V + packet.sol24V;

  ClientSocket1->Socket->SendBuf(&packet, sizeof(RS232_PACKET));
}
//---------------------------------------------------------------------------

void __fastcall TForm1::ClientSocket1Error(TObject *Sender,
      TCustomWinSocket *Socket, TErrorEvent ErrorEvent, int &ErrorCode)
{
  KILL_EVENT();
  StatusBar1->SimpleText = "Socket Error";
  ClientSocket1->Active = false;
  Button1->Caption = "Connect";
  Button1->Tag = 0;
   ErrorCode = 0;
   
}
//---------------------------------------------------------------------------

void __fastcall TForm1::Button4Click(TObject *Sender)
{
        char bs = SOCKCMD_PACK;
  ClientSocket1->Socket->SendBuf(&bs, 1);
}
//---------------------------------------------------------------------------

void __fastcall TForm1::Timer1Timer(TObject *Sender)
{
  static int packetcount;
  AnsiString s;
  
  if(Button1->Tag == 1 && ClientSocket1->Active)
  {
            if(CheckBox3->Checked)
            {
                char bs = SOCKCMD_PACK;
                bs = SOCKCMD_PACK ;
                ClientSocket1->Socket->SendBuf(&bs, 1);
            }

            struct RS232_PACKET
                  {
                         char sock_cmd;

                         char cmd;
                         char ch0duty;
                         char ch1duty;
                         char OE;
                         char sol12V;
                         char sol24V;
                         char checksum;
                  }
                  
//RS232 packet structure
//byte pos:  0       1      2       3       4      5        6            
//         ['F'][Ch0Duty][Ch1Duty][(OE)][Sol12V][Sol24V][Checksum]

                  packet = {SOCKCMD_FWDRS232, 'F', 0x00, 0x00, 0x55, 0x00, 0x00, 0x00};


         //construct solenoid bytes

            packet.sol12V = CheckBox5->Checked*2  +
                            CheckBox6->Checked*4+
                            CheckBox7->Checked*8+
                            CheckBox8->Checked*16+
                            CheckBox9->Checked*32+
                            CheckBox10->Checked*64+
                            CheckBox11->Checked*128;

            packet.sol24V = CheckBox12->Checked*1  +
                            CheckBox13->Checked*2+
                            CheckBox14->Checked*4+
                            CheckBox15->Checked*8+
                            CheckBox16->Checked*16+
                            CheckBox17->Checked*32+
                            CheckBox18->Checked*64;


//motor
        #define LEFTMASK 0x02
        #define RIGHTMASK 0x04

        if(CheckBox19->Checked)
        {
            int temp = TrackBar1->Position;

           // temp = 100*(temp-10);
            if(temp == 10) {
                    packet.ch0duty = 0;

            } else if(temp > 10) {//reverse direction

                packet.sol12V &= ~LEFTMASK;
                if(temp != 20)
                   packet.ch0duty = ((temp-10) % 10) * 10;
                  else
                   packet.ch0duty = 100;
             }  else {

                packet.sol12V |= LEFTMASK;
                if(temp != 20)
                   packet.ch0duty = (10-temp) * 10;
                  else
                   packet.ch0duty = 100;

              //  packet.ch0duty = (temp % 10) * 10;
            }


         ////////

            temp = TrackBar2->Position;

           // temp = 100*(temp-10);
            if(temp == 10) {
                    packet.ch1duty = 0;

            } else if(temp > 10) {//reverse direction

                packet.sol12V &= ~RIGHTMASK;
                if(temp != 20)
                   packet.ch1duty = ((temp-10) % 10) * 10;
                  else
                   packet.ch1duty = 100;
             }  else {

                packet.sol12V |= RIGHTMASK;
                if(temp != 20)
                   packet.ch1duty = (10-temp) * 10;
                  else
                   packet.ch1duty = 100;

              //  packet.ch0duty = (temp % 10) * 10;
            }

            //scale

                packet.ch0duty = 255*((float)packet.ch0duty/100);// % 256;
                 packet.ch1duty = 255*((float)packet.ch1duty/100);// % 256;
            } else {

                 packet.ch0duty = 255*((float)Label1->Caption.ToInt()/100);// % 256;
                 packet.ch1duty = 255*((float)Label2->Caption.ToInt()/100);// % 256;

                 if(Label3->Caption.ToInt() == 0) //rev??
                    packet.sol12V &= ~LEFTMASK;
                 else
                    packet.sol12V |= LEFTMASK;

                 if(Label4->Caption.ToInt() == 0)//forward??
                    packet.sol12V &= ~RIGHTMASK;
                 else
                    packet.sol12V |= RIGHTMASK;
            }




           if(CheckBox3->Checked)
           {
               packet.OE = 0xAA;
           } else {
               packet.OE = 0x55;
           }

            packet.checksum = packet.ch0duty + packet.ch1duty + packet.OE + packet.sol12V + packet.sol24V;

            ClientSocket1->Socket->SendBuf(&packet, sizeof(RS232_PACKET));
            s.printf("Sent packet %d", packetcount);
            packetcount++;
            
            StatusBar1->SimpleText = s;

      
  }
}
//---------------------------------------------------------------------------

void __fastcall TForm1::FormMouseMove(TObject *Sender, TShiftState Shift,
      int X, int Y)
{
       if(!CheckBox1->Checked) return;

         struct RS232_PACKET
        {
               char sock_cmd;

               char cmd;
               char ch0duty;
               char ch1duty;
               char OE;
               char sol12V;
               char sol24V;
               char checksum;
        }packet = {SOCKCMD_FWDRS232, 'F', 0xAA, 0xAA, 0xAA, 0xBB, 0xCC, 0x00};


      packet.sol12V= X % 255;

      packet.checksum = packet.ch0duty + packet.ch1duty + packet.OE + packet.sol12V + packet.sol24V;
      AnsiString s;
      s.printf("Mouse Track: %d", X % 255);
      StatusBar1->SimpleText = s;
      
  ClientSocket1->Socket->SendBuf(&packet, sizeof(RS232_PACKET));
}
//---------------------------------------------------------------------------

void __fastcall TForm1::FormKeyDown(TObject *Sender, WORD &Key,
      TShiftState Shift)
{
    AnsiString s;
    s.printf("Key Down: %d", Key);
    Memo1->Lines->Add(s);
}
//---------------------------------------------------------------------------

void __fastcall TForm1::FormKeyPress(TObject *Sender, char &Key)
{
           AnsiString s;
    s.printf("Key Down: %d", Key);
    Memo1->Lines->Add(s);
}
//---------------------------------------------------------------------------


void __fastcall TForm1::Button5Click(TObject *Sender)
{
//   Form2->Show();
            int temp = TrackBar1->Position;

         //   temp = 100*(temp-10);
            if(temp / 10 == 0) {//reverse direction

             }  else {

            }
            temp = (temp % 10) * 100;
}
//---------------------------------------------------------------------------

void __fastcall TForm1::CheckBox4Click(TObject *Sender)
{
  Form1->Focused();        
}
//---------------------------------------------------------------------------


void __fastcall TForm1::Memo1KeyUp(TObject *Sender, WORD &Key,
      TShiftState Shift)
{
    AnsiString s;
    s.printf("memo Key up: %d", Key);
    Memo1->Lines->Add(s);

    if(keys.size())
    {
        for(int i = 0; i < keys.size(); i++)
        {
                if(keys[i] == Key) {
                  s.printf("removed key %d %d", i, keys[i]);
                      Memo1->Lines->Add(s);
                  keys.erase(keys.begin()+i, keys.begin()+i+1);
                  }
        }

    }

    switch(Key)
    {
        case 37: //left arrow
               // Label5->Caption = "Halt";
               // break;
        case 38: //up
               // Label5->Caption = "Halt";
               // break;
        case 39: //right
               // Label5->Caption = "Halt";
               // break;
        case 40: //down

                Label1->Caption = 0;
                Label2->Caption = 0;
                Label3->Caption = 0;
                Label4->Caption = 0;

                Label5->Caption = "Halt";
                break;
        default:
        ;
    }
    s.printf("Active keys: %d", keys.size());
    Memo1->Lines->Add(s);
    
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Memo1KeyDown(TObject *Sender, WORD &Key,
      TShiftState Shift)
{
    AnsiString s;
    s.printf("memo Key Down: %d", Key);

    if(CheckBox4->Checked)
    {
        if(keys.size()) //checkbox4 = live keyboard
        {
            for(int i = 0; i < keys.size(); i++)
            {
                    if(keys[i] == Key) goto bah;
            }
            keys.push_back(Key);

        }   else {
          keys.push_back(Key);
        }


    #define CHECKER(i) CheckBox##i##->Checked = !CheckBox##i##->Checked
    switch (Key)
    {
        case 'Q':
               // CheckBox5->Checked = !CheckBox5->Checked;
               CHECKER(5);
                break;
        case 'W':
               CHECKER(6);
                break;
        case 'E':
               CHECKER(7);

                break;
        case 'R':
               CHECKER(8);
                break;
        case 'T':
               CHECKER(9);
                break;
        case 'Y':
               CHECKER(10);
                break;

        case 'U':
               CHECKER(11);
                break;
        //BEGIN 24V
        case 'A':
               CHECKER(12);
                break;
        case 'S':
               CHECKER(13);
                break;
        case 'D':
               CHECKER(14);
                break;
        case 'F':
               CHECKER(15);
                break;
        case 'G':
               CHECKER(16);
                break;
        case 'H':
               CHECKER(17);
                break;
        case 'J':
               CHECKER(18);
                break;

        case 37: //left arrow
                Label1->Caption = Edit2->Text.ToInt();
                Label2->Caption = Edit2->Text.ToInt();
                Label3->Caption = "1";
                Label4->Caption = "0";
                Label5->Caption = "Rotate CCW";
                break;
        case 38: //up
                Label1->Caption = Edit2->Text.ToInt();
                Label2->Caption = Edit2->Text.ToInt();
                Label3->Caption = "0";
                Label4->Caption = "0";
                Label5->Caption = "FORWARD";
                break;
        case 39: //right
                Label1->Caption = Edit2->Text.ToInt();
                Label2->Caption = Edit2->Text.ToInt();
                Label3->Caption = "0";
                Label4->Caption = "1";
                Label5->Caption = "Rotate CW";
                break;
        case 40: //down
                Label1->Caption = Edit2->Text.ToInt();
                Label2->Caption = Edit2->Text.ToInt();
                Label3->Caption = "1";
                Label4->Caption = "1";
                Label5->Caption = "REVERSE";
                break;
        default:
        ;

    }
    }
     Memo1->Lines->Add(s);


    // Form1->Owner
     //Form1->Handle
    bah:
    return;
}
//---------------------------------------------------------------------------


void __fastcall TForm1::Button6Click(TObject *Sender)
{
/*
TCheckBox *dude;

dude = new TCheckBox(Form1->Handle);
dude->PaintTo(Form1->Canvas, 100, 100);
dude->Visible = true;
  */
  TrackBar1->Position = Edit1->Text.ToInt();
TrackBar1->SetTick(Edit1->Text.ToInt());
}
//---------------------------------------------------------------------------

void __fastcall TForm1::Button7Click(TObject *Sender)
{

    //Image1->Canvas->LineTo(10,10);
     Image1->  Canvas->FillRect(ClientRect);
  /*  Image1->Canvas->MoveTo(10, 3);
  Image1->Canvas->LineTo(12, 26);
    */

    POINT points[6];
  Image1->Canvas->Pen->Color = clBlack;
  #define STARTX 10
  #define STARTY 10
  points[0].x = STARTX;
  points[0].y = STARTY;

  points[1].x = STARTX;
  points[1].y = STARTY+30;

  points[2].x = STARTX-5;
  points[2].y = STARTY+30-5;

  points[3].x = STARTX+5;
  points[3].y = STARTY+30-5;

  points[4].x = STARTX;
  points[4].y = STARTY+30;

//  points[5].x = 40;
 // points[5].y = 10;
  Image1->Canvas->Polyline((TPoint*)points,4);

   //Shape1->DrawTextBiDiModeFlags()
}
//---------------------------------------------------------------------------

void __fastcall TForm1::Button8Click(TObject *Sender)
{
  char bs = SOCKCMD_PACK;
            bs = SOCKCMD_PACK ;
        //    ClientSocket1->Socket->SendBuf(&bs, 1);
             AnsiString s;

            struct RS232_PACKET
                  {
                         char sock_cmd;

                         char cmd;
                         char ch0duty;
                         char ch1duty;
                         char OE;
                         char sol12V;
                         char sol24V;
                         char checksum;
                  }
                  
//RS232 packet structure
//byte pos:  0       1      2       3       4      5        6            
//         ['F'][Ch0Duty][Ch1Duty][(OE)][Sol12V][Sol24V][Checksum]

                  packet = {SOCKCMD_FWDRS232, 'F', 0x00, 0x00, 0xAA, 0x00, 0x00, 0x00};

            packet.ch0duty = Edit1->Text.ToInt();
            packet.ch1duty = Edit1->Text.ToInt();
            
            
            packet.cmd = 'C';

            packet.sol12V = CheckBox5->Checked*2  +
                            CheckBox6->Checked*4+
                            CheckBox7->Checked*8+
                            CheckBox8->Checked*16+
                            CheckBox9->Checked*32+
                            CheckBox10->Checked*64+
                            CheckBox11->Checked*128;

            packet.sol24V = CheckBox12->Checked*1  +
                            CheckBox13->Checked*2+
                            CheckBox14->Checked*4+
                            CheckBox15->Checked*8+
                            CheckBox16->Checked*16+
                            CheckBox17->Checked*32+
                            CheckBox18->Checked*64;

            // packet.ch0duty = Label1->Caption.ToInt() % 256;
            // packet.ch1duty = Label2->Caption.ToInt() % 256;



            packet.checksum = packet.ch0duty + packet.ch1duty + packet.OE + packet.sol12V + packet.sol24V;

            ClientSocket1->Socket->SendBuf(&packet, sizeof(RS232_PACKET));
            //s.printf("Sent packet %d", packetcount);
            //packetcount++;

            //StatusBar1->SimpleText = s;
}
//---------------------------------------------------------------------------

void __fastcall TForm1::Button9Click(TObject *Sender)
{
   TrackBar1->Position = 10;
   TrackBar2->Position = 10;        
}
//---------------------------------------------------------------------------

void __fastcall TForm1::TrackBar2Change(TObject *Sender)
{
            int temp = TrackBar2->Position;

            Memo1->Lines->Add(temp);

           // temp = 100*(temp-10);
            if(temp == 10) {
                    temp = 0;

            } else if(temp > 10) {//reverse direction

                if(temp != 20)
                   temp = ((temp-10) % 10) * 10;
                  else
                   temp = 100;
             }  else {

                if(temp != 20)
                   temp = ((temp-10) % 10) * 10;
                  else
                   temp = 100;

                temp= (temp % 10) * 10;
            }

            Memo1->Lines->Add(temp);
            Memo1->Lines->Add(" ");
}
//---------------------------------------------------------------------------


void __fastcall TForm1::TrackBar1Change(TObject *Sender)
{
            int temp = TrackBar1->Position;

            Memo1->Lines->Add(temp);

           // temp = 100*(temp-10);
            if(temp == 10) {
                    temp = 0;

            } else if(temp > 10) {//reverse direction

                if(temp != 20)
                   temp = ((temp-10) % 10) * 10;
                  else
                   temp = 100;
             }  else {

                if(temp != 20)
                   temp = ((10-temp)) * 10;
                  else
                   temp = 100;

               // temp = (temp % 10) * 10;
            }

            Memo1->Lines->Add(temp);
            Memo1->Lines->Add(" ");        
}
//---------------------------------------------------------------------------

